# coding:utf-8
'''
Created on 2011-3-6
获取文件基本信息的框架。

框架会返回包含文件基本信息键值对的dictionary。
可以添加各种类型文件的解析类（如：HTMLFileInfo、MPGFileInfo、DOCFileInfo等）到框架中。
@author: Administrator
'''
import os
import sys
from UserDict import UserDict

def stripnulls(data):
    "移除数据中的空白字符"
    return data.replace("\00", "").strip();

class FileInfo(UserDict):
    "存储文件基本信息"
    def __init__(self, filename=None):
        UserDict.__init__(self)
        self["name"] = filename
        
class MP3FileInfo(FileInfo):
    "储存MP3的基本信息"
    tagDataMap = {"title" : (3, 33, stripnulls),
                  "artist" : (33, 63, stripnulls),
                  "album" : (63, 93, stripnulls),
                  "year" : (93, 97, stripnulls),
                  "comment" : (97, 126, stripnulls),
                  "genre" : (127, 128, ord)}
    def __parse(self, filename):
        "从MP3文件中解析出基本信息"
        self.clear()
        try:
            fsock = open(filename, "rb", 0)
            try:
                fsock.seek(-128, 2)
                tagdata = fsock.read(128)
            finally:
                fsock.close()
            if tagdata[:3] == 'TAG':
                for tag, (start, end, parseFunc) in self.tagDataMap.items():
                    self[tag] = parseFunc(tagdata[start:end])
        except IOError:
            pass
    
    def __setitem__(self, key, item): # __setitem__是重写UserDict的方法，在添加元素时执行
        if key == "name" and item:
            self.__parse(item)
        FileInfo.__setitem__(self, key, item)
    
def listDir(dir, fileExtList):
    "读取指定目录（dir）下所有符合拓展名要求（fileExtList）的所有文件"
    fileList = [os.path.normcase(f) for f in os.listdir(dir)]
    fileList = [os.path.join(dir, f) for f in fileList
                if os.path.splitext(f)[1] in fileExtList]
    def getFileInfoClass(filename, module=sys.modules[FileInfo.__module__]):
        "根据文件拓展名获取相应的文件信息储存类，默认为FileInfo"
        subclass = "%sFileInfo" % os.path.splitext(filename)[1].upper()[1:]
        return hasattr(module, subclass) and getattr(module, subclass) or FileInfo
    return [getFileInfoClass(f)(f) for f in fileList]

if __name__ == "__main__":
    for info in listDir("E:\MP3\Vitas", ".mp3"):
        print "\n".join(["%s=%s" % (k, v) for k, v in info.items()])
        print
        
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
